{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "hi"
   },
   "source": [
    "# भाग 2: Syft Keras निर्देशित सुरक्षित मॉडल के साथ काम करना\n",
    "\n",
    "अब जब आपके पास सामान्य Keras के साथ एक प्रशिक्षित मॉडल है, तो आप कुछ निजी पूर्वानुमान की सेवा के लिए तैयार हैं। हम Syft Keras का उपयोग कर सकते हैं।\n",
    "\n",
    "इस मॉडल को सुरक्षित करने और सेवा करने के लिए, हमें तीन TFEWorkers (सर्वर) की आवश्यकता होगी। इसका कारण यह है कि TF एनक्रिप्टेड हुड के तहत एक एन्क्रिप्शन तकनीक का उपयोग करता है जिसे [बहु-पक्षीय संगणना (MPC)](https://en.wikipedia.org/wiki/Secure) कहा जाता है। अवधारणा अनुसार, मॉडल वज़न और इनपुट डेटा को शेयरों में विभाजित किया जाता है, फिर प्रत्येक मूल्य का एक हिस्सा अलग-अलग सर्वरों को भेजा जाता है। प्रमुख संपत्ति यह है कि यदि आप एक सर्वर पर शेयर को देखते हैं, तो यह मूल मूल्य (इनपुट डेटा या मॉडल वज़न) के बारे में कुछ नहीं बताता है।\n",
    "\n",
    "हम एक Syft Keras मॉडल को परिभाषित करेंगे जैसे हमने पिछले नोटबुक में किया था। हालाँकि, एक ट्रिक है: इस मॉडल को इंस्टेंट करने से पहले, हम `hook = sy.KerasHook (tf.keras)` चलाएंगे। यह केरस अनुक्रमिक वर्ग में तीन महत्वपूर्ण नए तरीके जोड़ देगा:\n",
    " - `share`: गुप्त साझाकरण के माध्यम से अपने मॉडल को सुरक्षित करेगा; डिफ़ॉल्ट रूप से, यह टीएफ एनक्रिप्टेड से सिक्योरएनएन प्रोटोकॉल का उपयोग करके तीन TFEWorkers में से प्रत्येक के बीच अपने मॉडल को गुप्त रूप से साझा करेगा। सबसे महत्वपूर्ण बात, यह एन्क्रिप्टेड डेटा पर पूर्वानुमान प्रदान करने की क्षमता को जोड़ देगा।\n",
    " - `serve`: यह फ़ंक्शन एक सर्विंग कतार लॉन्च करेगा, ताकि TFEWorkers बाहरी ग्राहकों से सुरक्षित मॉडल पर पूर्वानुमान के अनुरोधों को स्वीकार कर सकें।\n",
    " - `shutdown_workers`: एक बार जब आप निजी भविष्यवाणियाँ प्रदान करते हैं, तो आप इस फ़ंक्शन को चलाकर अपने मॉडल को बंद कर सकते हैं। यदि आप मैन्युअल रूप से प्रत्येक कार्यकर्ता को प्रबंधित करने का विकल्प चुनते हैं तो यह आपको मैन्युअल रूप से सर्वर प्रक्रियाओं को बंद करने के लिए निर्देशित करेगा।\n",
    "\n",
    "यदि आप MPC के बारे में अधिक जानना चाहते हैं, तो आप इस उत्कृष्ट [ब्लॉग](https://mortendahl.github.io/2017/04/17/pStreet-deep-learning-with-mpc/) को पढ़ सकते हैं।"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "अनुवादक - nbTranslate \n",
    "\n",
    "संपादक - Urvashi Raheja - Github: [@raheja](https://github.com/raheja)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "from tensorflow.keras import Sequential\n",
    "from tensorflow.keras.layers import AveragePooling2D, Conv2D, Dense, Activation, Flatten, ReLU, Activation\n",
    "\n",
    "import syft as sy\n",
    "hook = sy.KerasHook(tf.keras)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "hi"
   },
   "source": [
    "## मॉडल"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "hi"
   },
   "source": [
    "जैसा कि आप देख सकते हैं, हम लगभग एक ही मॉडल को पहले की तरह परिभाषित करते हैं, सिवाय इसके कि हम एक 'batch_input_shape' प्रदान करते हैं। यह पूर्वनिर्मित टेनसर आकृतियों के माध्यम से सुरक्षित गणनाओं को बेहतर ढंग से अनुकूलित करने के लिए TF एन्क्रिप्टेड को अनुमति देता है। इस MNIST डेमो के लिए, हम (1, 28, 28, 1) के आकार के साथ इनपुट डेटा भेजेंगे।\n",
    "हम सॉफ्टमैक्स के बजाय लॉगिट को भी लौटाते हैं क्योंकि यह ऑपरेशन एमपीसी का उपयोग करने के लिए जटिल है, और हमें पूर्वानुमान अनुरोधों को पूरा करने के लिए इसकी आवश्यकता नहीं है।"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "num_classes = 10\n",
    "input_shape = (1, 28, 28, 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From /usr/local/miniconda3/envs/syft/lib/python3.6/site-packages/tensorflow/python/ops/resource_variable_ops.py:435: colocate_with (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Colocations handled automatically by placer.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From /usr/local/miniconda3/envs/syft/lib/python3.6/site-packages/tensorflow/python/ops/resource_variable_ops.py:435: colocate_with (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Colocations handled automatically by placer.\n"
     ]
    }
   ],
   "source": [
    "model = Sequential()\n",
    "\n",
    "model.add(Conv2D(10, (3, 3), batch_input_shape=input_shape))\n",
    "model.add(AveragePooling2D((2, 2)))\n",
    "model.add(Activation('relu'))\n",
    "model.add(Conv2D(32, (3, 3)))\n",
    "model.add(AveragePooling2D((2, 2)))\n",
    "model.add(Activation('relu'))\n",
    "model.add(Conv2D(64, (3, 3)))\n",
    "model.add(AveragePooling2D((2, 2)))\n",
    "model.add(Activation('relu'))\n",
    "model.add(Flatten())\n",
    "model.add(Dense(num_classes, name=\"logit\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "hi"
   },
   "source": [
    "### पूर्व प्रशिक्षित भार को लोड करें"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "hi"
   },
   "source": [
    "`load_weights` के साथ आप अपने मॉडल को प्रशिक्षित करने के बाद पहले से बचाए गए भार (weights) को आसानी से लोड कर सकते हैं।"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "pre_trained_weights = 'short-conv-mnist.h5'\n",
    "model.load_weights(pre_trained_weights)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "hi"
   },
   "source": [
    "### कार्यकर्ताओं को लॉन्च करें"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "hi"
   },
   "source": [
    "चलो अब TFEWorkers (`alice`,` bob`, और `carol`) का निर्माण TF Encrypted द्वारा निजी भविष्यवाणियों को करने के लिए आवश्यक है। प्रत्येक TFEWorker के लिए, आपको बस एक होस्ट निर्दिष्ट करना होगा। हम फिर इन श्रमिकों को एक क्लस्टर में जोड़ देते हैं।\n",
    "\n",
    "ये कार्यकर्ता एक [TensorFlow सर्वर](https://www.tensorflow.org/api_docs/python/tf/distribute/Server) चलाते हैं, जिन्हें आप या तो मैन्युअल रूप से प्रबंधित कर सकते हैं (`AUTO = False`) या श्रमिकों को प्रबंधित करने के लिए कहें। आप (`AUTO = True`)। यदि उन्हें मैन्युअल रूप से प्रबंधित करने के लिए चुना जाता है, तो आपको नीचे दिए गए `cluster.start()` को कॉल करने के बाद प्रत्येक कार्यकर्ता के होस्ट डिवाइस पर एक टर्मिनल कमांड निष्पादित करने का निर्देश दिया जाएगा। यदि सभी श्रमिकों को एक एकल डिवाइस (जैसे `localhost`) पर होस्ट किया जाता है, तो आप कार्यकर्ता के टेन्सरफ्लो सर्वर को स्वचालित रूप से प्रबंधित करने के लिए सिफ्ट का चयन कर सकते हैं।"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tf_encrypted:If not done already, please launch the following command in a terminal on host localhost:4000: 'python -m tf_encrypted.player --config /var/folders/mh/7hh_sz1d3532_k9w4kcmnt8c0000gn/T/tfe.config server0'\n",
      "This can be done automatically in a local subprocess by setting `auto_managed=True` when instantiating a TFEWorker.\n",
      "\n",
      "INFO:tf_encrypted:If not done already, please launch the following command in a terminal on host localhost:4001: 'python -m tf_encrypted.player --config /var/folders/mh/7hh_sz1d3532_k9w4kcmnt8c0000gn/T/tfe.config server1'\n",
      "This can be done automatically in a local subprocess by setting `auto_managed=True` when instantiating a TFEWorker.\n",
      "\n",
      "INFO:tf_encrypted:If not done already, please launch the following command in a terminal on host localhost:4002: 'python -m tf_encrypted.player --config /var/folders/mh/7hh_sz1d3532_k9w4kcmnt8c0000gn/T/tfe.config server2'\n",
      "This can be done automatically in a local subprocess by setting `auto_managed=True` when instantiating a TFEWorker.\n",
      "\n"
     ]
    }
   ],
   "source": [
    "AUTO = False\n",
    "\n",
    "alice = sy.TFEWorker(host='localhost:4000', auto_managed=AUTO)\n",
    "bob = sy.TFEWorker(host='localhost:4001', auto_managed=AUTO)\n",
    "carol = sy.TFEWorker(host='localhost:4002', auto_managed=AUTO)\n",
    "\n",
    "cluster = sy.TFECluster(alice, bob, carol)\n",
    "cluster.start()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "hi"
   },
   "source": [
    "### वजन साझा करके मॉडल को सुरक्षित करें"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "hi"
   },
   "source": [
    "`sy.KerasHook (tf.keras) के कारण` आप अपने मॉडल को TF एन्क्रिप्ट किए गए Keras मॉडल में बदलने के लिए `share` विधि कह सकते हैं।\n",
    "\n",
    "यदि आपने ऊपर दिए गए सर्वरों को मैन्युअल रूप से प्रबंधित करने के लिए कहा है, तो यह चरण तब तक पूरा नहीं होगा जब तक कि वे सभी लॉन्च नहीं हो जाते। ध्यान दें कि आपका फ़ायरवॉल आने वाले कनेक्शन को स्वीकार करने के लिए पायथन से पूछ सकता है।"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "lang": "en",
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tf_encrypted:Starting session on target 'grpc://localhost:4000' using config graph_options {\n",
      "}\n",
      "\n"
     ]
    }
   ],
   "source": [
    "model.share(cluster)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "en"
   },
   "source": [
    "### Serve model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Served encrypted prediction 1 to client.\n",
      "Served encrypted prediction 2 to client.\n",
      "Served encrypted prediction 3 to client.\n"
     ]
    }
   ],
   "source": [
    "model.serve(num_requests=3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "hi"
   },
   "source": [
    "आप कुछ निजी भविष्यवाणियों का अनुरोध करने के लिए **भाग 13c** नोटबुक पर जाने के लिए तैयार हैं।"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "hi"
   },
   "source": [
    "### साफ - सफाई!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "hi"
   },
   "source": [
    "एक बार आपके अनुरोध की सीमा ऊपर हो जाने के बाद, मॉडल अब सेवारत अनुरोधों के लिए उपलब्ध नहीं होगा, लेकिन यह अभी भी उपरोक्त तीन श्रमिकों के बीच साझा किया गया रहस्य है। आप नीचे सेल को निष्पादित करके श्रमिकों को मार सकते हैं।\n",
    "\n",
    "**बधाई** भाग 13 बी खत्म करने पर: सिफ्ट केरस और टीएफई के साथ सुरक्षित वर्गीकरण!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tf_encrypted:Please terminate the process on host 'localhost:4000'.\n",
      "INFO:tf_encrypted:Please terminate the process on host 'localhost:4001'.\n",
      "INFO:tf_encrypted:Please terminate the process on host 'localhost:4002'.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Process ID 12470 has been killed.\n",
      "Process ID 12474 has been killed.\n",
      "Process ID 12464 has been killed.\n"
     ]
    }
   ],
   "source": [
    "model.stop()\n",
    "cluster.stop()\n",
    "\n",
    "if not AUTO:\n",
    "    process_ids = !ps aux | grep '[p]ython -m tf_encrypted.player --config' | awk '{print $2}'\n",
    "    for process_id in process_ids:\n",
    "        !kill {process_id}\n",
    "        print(\"Process ID {id} has been killed.\".format(id=process_id))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  },
  "nbTranslate": {
   "displayLangs": [
    "hi"
   ],
   "hotkey": "alt-t",
   "langInMainMenu": true,
   "sourceLang": "en",
   "targetLang": "hi",
   "useGoogleTranslate": true
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
